
local Entity = import(".Entity")
local ActNames = import("..models.ActNames")
local Person = class("Person", Entity)

local scheduler = cc.Director:getInstance():getScheduler()
Person.MOVE_STEP_TIME = 0.12
Person.CAMERA_UPDATE_TIME = 0.2

function Person:ctor(args)
	
	local sm = cc.load("statemachine")
	args.states = {
		events = {
			{name = "born",		from = "none",   		to = "idle" },
			{name = "move",		from = {"idle", "walk"},to = "walk" },
			{name = "attack",	from = "idle",   		to = "atk" },
			{name = "stop",		from = {"walk", "atk"}, to = "idle" },
			{name = "kill",   	from = sm.WILDCARD,   	to = "death" }
		}
	}
	
	self.orientation = args.orientation or Constants.fowardOrientation
	self.path_ = {}
	Person.super.ctor(self, args)  
end

function Person:doEvent(eventName)
	if self.fsm_:canDoEvent(eventName) then
		self.fsm_:doEvent(eventName)
	end
end

function Person:onAfterEvent(event)
	Entity.onAfterEvent(self, event)

	if "walk" == event.to then
		self:dispatchEvent({name = "move"})
		self:playWalk(self.orientation)
	elseif "atk" == event.to then
		self:playAtk()
	end
end

function Person:walkToPos(destPos, origPos)
	local path = ManagerMap:findPath(destPos, origPos)
	self:walkPath(path)
end

function Person:getCurPos()
	return ManagerMap:px2pos({x = self.view_:getPositionX(), y = self.view_:getPositionY()})
end

function Person:_walkTo(toPos)
	if not toPos then
		return
	end
	local curPos = self:getMapPos()
	local orientation =  ManagerMap:getOrientation(toPos,curPos)
	local dis = math.sqrt(math.pow((toPos.x - curPos.x),2) + math.pow((toPos.y - curPos.y),2))
	if not orientation then
		-- the same, needn't walk
		print("Person:_walkTo is same")
		return
	end
	
	--启动摄像机追踪
	if self.cameraFollow == nil and self.camera  then
		self.cameraFollow = scheduler:scheduleScriptFunc(function()
			self.camera:look(self, Person.CAMERA_UPDATE_TIME)
		end, Person.CAMERA_UPDATE_TIME, false)
	end
	local args = ManagerMap:pos2px(toPos)
	args.time = dis * Person.MOVE_STEP_TIME
	args.onComplete = handler(self, self.onWalkStepComplete_)
	self.isWalking_ = true
	self.view_:stopAllActions()
	self.view_:moveTo(args)
	self.orientation = orientation
	self:doEvent("move")

end

function Person:walkPath(path)
	if not path then
		printInfo("Person:walkPath path is nil")
		return
	end
	local curPos = self:getMapPos()
	if path[1].x == curPos.x and path[1].y == curPos.y then
		table.remove(path, 1)
	end

	if #path < 1 then
		printInfo("Person:walkPath path length is 0")
		return
	end

	self.path_ = path

	--if not self.isWalking_ then
	self:_walkTo(table.remove(self.path_, 1))
	--end
end


function Person:onWalkStepComplete_()
	self.isWalking_ = false

	printInfo("Person:onWalkStepComplete_ %d path count:%d", self.id, #self.path_)
	if 0 == #self.path_ then
		self:doEvent("stop")
		----关闭摄像机追踪
		if self.cameraFollow then 
			scheduler:unscheduleScriptEntry(self.cameraFollow)
			self.cameraFollow = nil
		end
		-- if Game:isSelf(self) then
		-- 	self:sendInfoToServer()
		-- end
		-- if 1 == self:distanceWith(self.attackEntity_) then
		-- 	self:attackReqAuto()
		-- elseif 1 == self:distanceWith(self.talkEntity_) then
		-- 	self:talk()
		-- elseif 1 == self:distanceWith(self.lootEntity_) then
		-- 	self:lootItemReq()
		-- end
	else
		self:_walkTo(table.remove(self.path_, 1))
	end
end

function Person:playWalk(orientation)
	printInfo("Person play walk",orientation,ActNames[orientation])
	if self.lastOrientation ~= orientation then
		local actionName = ActNames[orientation]
		self:play(actionName)
		self.lastOrientation = orientation
	end
end

function Person:sendInfoToServer()
	if 0 == self.id then
		return
	end

	-- Game:sendCmd("user.info",
	-- 	{id = self.id,
	-- 	pos = self.curPos_,
	-- 	orientation = self.orientation_})
end

return Person
